package ldh.im.fxgui.component.message;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import ldh.im.fxbase.util.FxThreadUtil;
import ldh.im.fxgui.handle.IMessageEditorHandler;
import ldh.im.fxbase.util.ThreadPoolUtil;
import ldh.im.fxbase.data.pojo.ImMessage;
import ldh.im.fxgui.component.message.bo.WrapImMessage;
import ldh.im.fxgui.service.MessageReadService;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MessageVBoxListView extends BaseMessageListViewHandler {

    private ObservableList<WrapImMessage> items = FXCollections.observableArrayList();
    private VBox messageList;
    private ScrollPane scrollPane;

    public MessageVBoxListView(IMessageEditorHandler messageEditorService, StackPane dialogRoot, int maxSize) {
        super(messageEditorService, dialogRoot);
        setLimitTotal(maxSize);
    }

    public Node createMessagePaneNode() {
        messageList = new VBox();
        scrollPane = new ScrollPane(messageList);
        return scrollPane;
    }

    @Override
    public boolean addMessage(ImMessage message) {
        if (!imSession.getId().equals(message.getSessionId())) return false;
        removeMore();
        WrapImMessage wrapImMessage = WrapImMessage.wrap(message);
        items.add(wrapImMessage);
        messageList.getChildren().add(createMessagePane(wrapImMessage));
        scrollPane.setVvalue(1.0);
        ThreadPoolUtil.schedule(()-> {
            FxThreadUtil.runLater(()-> scrollPane.setVvalue(1.0));
        }, 10);
        return true;
    }

    @Override
    public void addMessage(int index, ImMessage message) {
        if (!imSession.getId().equals(message.getSessionId())) return;

        WrapImMessage wrapImMessage = WrapImMessage.wrap(message);
        items.add(index, wrapImMessage);
        messageList.getChildren().add(createMessagePane(wrapImMessage));
        scrollPane.setVvalue(1.0);
        ThreadPoolUtil.schedule(()-> {
            FxThreadUtil.runLater(()-> scrollPane.setVvalue(1.0));
        }, 10);
    }

    @Override
    public void addMessages(List<ImMessage> messages) {
        if (!imSession.getId().equals(messages.get(0).getSessionId())) return;
        List<WrapImMessage> wrapImMessages = messages.stream().map(m->WrapImMessage.wrap(m)).collect(Collectors.toList());
        items.addAll(wrapImMessages);
        for(WrapImMessage message : wrapImMessages) {
            messageList.getChildren().add(createMessagePane(message));
        }
        scrollPane.setVvalue(1.0);
        ThreadPoolUtil.schedule(()-> {
            FxThreadUtil.runLater(()-> scrollPane.setVvalue(1.0));
        }, 10);
    }

    @Override
    public void addFrontMessages(List<ImMessage> messages) {
        if (!imSession.getId().equals(messages.get(0).getSessionId())) return;
    }

    @Override
    public void updateMessage(ImMessage message) {
        if (!imSession.getId().equals(message.getSessionId())) return;

        WrapImMessage wrapImMessage = WrapImMessage.wrap(message);
        int idx = items.indexOf(wrapImMessage);
        if (idx > 0) {
            wrapImMessage = items.get(idx);
            items.remove(message);
            items.add(idx, wrapImMessage);

            if (message.isAttachFile()) {
                MessageReadService.getInstance().asyHandleReadMessage(message.getSessionId(), message.getCurrentUserId(), Arrays.asList(message));
            }
        }
    }

    @Override
    public ObservableList<WrapImMessage> getItems() {
        return items;
    }

    @Override
    protected int removeMore() {
        if (items.size() > limitTotal) {
            int removeSize = items.size() - limitTotal;
            items.remove(0, removeSize);
            messageList.getChildren().remove(0, removeSize);
            return removeSize;
        }
        return 0;
    }
}
